#include "AnimatedEntity.h"
#include "World.h"

void AnimatedEntity::clearWeapon()
{
	if (weaponMesh__)
	{
		// World::getSceneManager()->getMeshCache()->removeMesh(weaponMesh__);
		weaponMesh__ = 0;
	}
	
	if (weaponNode__)
	{
		// It is theorically useless to excplicit remove the node from node__
		weaponNode__->remove();
		weaponNode__ = 0;
	}
}

IAnimatedMesh* AnimatedEntity::getEntityMesh(){return entityMesh__;}

AnimatedEntity::AnimatedEntity(const irr::core::string<c8>& entityModel, const irr::core::string<c8>& entitySkin, const irr::core::string<c8>& weaponModel, const irr::core::string<c8>& weaponSkin): Entity()
{
	entityMesh__ = smgr__->getMesh(entityModel.c_str());
	node__ = smgr__->addAnimatedMeshSceneNode(entityMesh__);
	node__->setMaterialTexture(0, World::getVideoDriver()->getTexture(entitySkin.c_str()));
	node__->setMaterialFlag(EMF_LIGHTING, false);

	node__->setID(4); // FIXME: ID is set to 4, for now

	weaponMesh__ = 0;
	weaponNode__ = 0;

	setWeapon(weaponModel, weaponSkin);

	animFrames__ = std::pair<s32, s32>(0, 0);
	animString__ = "";
}

AnimatedEntity::~AnimatedEntity()
{
	if (entityMesh__)
	{
		// World::getSceneManager()->getMeshCache()->removeMesh(entityMesh__);
		entityMesh__ = 0;
	}

	clearWeapon();

	// Note: node__ dropped in ~Entity()
}

void AnimatedEntity::setAnimation(std::pair<s32, s32> frames, bool loop)
{
	if (animFrames__ == frames)
		return;
	
	getNode()->setLoopMode(loop);
	getNode()->setFrameLoop(frames.first, frames.second);
	
	if (weaponNode__)
	{
		weaponNode__->setLoopMode(loop);
		weaponNode__->setFrameLoop(frames.first, frames.second);
	}

	animFrames__ = frames;
}

void AnimatedEntity::setAnimation(s32 start, s32 end, bool loop)
{
	setAnimation(std::pair<s32, s32>(start, end), loop);
}

bool AnimatedEntity::setAnimation(const irr::core::string<c8>& animName, bool loop)
{
	if (animName == animString__)
		return true;
	
	bool ret = false;

	getNode()->setLoopMode(loop);
	ret = getNode()->setMD2Animation(animName.c_str());

	if (weaponNode__)
	{
		weaponNode__->setLoopMode(loop);
		ret &= weaponNode__->setMD2Animation(animName.c_str());
	}

	animString__ = animName;
	return ret;
}

bool AnimatedEntity::setAnimation(EMD2_ANIMATION_TYPE animName, bool loop)
{
	if (animType__ == animName)
		return true;
	
	bool ret = false;

	getNode()->setLoopMode(loop);
	ret = getNode()->setMD2Animation(animName);

	if (weaponNode__)
	{
		weaponNode__->setLoopMode(loop);
		ret &= weaponNode__->setMD2Animation(animName);
	}

	animType__ = animName;
	return ret;
}

void AnimatedEntity::setWeapon(const irr::core::string<c8>& weaponModel, const irr::core::string<c8>& weaponSkin)
{
	clearWeapon();

	if (weaponModel != "")
	{
		weaponMesh__ = smgr__->getMesh(weaponModel.c_str());
		weaponNode__ = smgr__->addAnimatedMeshSceneNode(weaponMesh__, node__);
		weaponNode__->setMaterialTexture(0, World::getVideoDriver()->getTexture(weaponSkin.c_str()));
		weaponNode__->setMaterialFlag(EMF_LIGHTING, false);
		weaponNode__->setID(4);
		weaponNode__->setName("AnimatedEntity::weaponNode__");
	}
}

IAnimatedMeshSceneNode* AnimatedEntity::getNode()
{
	return dynamic_cast<IAnimatedMeshSceneNode*>(node__);
}

IAnimatedMeshSceneNode* AnimatedEntity::getMeshNode() 
{
	return dynamic_cast<IAnimatedMeshSceneNode*>(node__);
}

